package com.hl.card.modular.packBack.service.impl;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang.StringUtils;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.hl.card.common.persistence.dao.SysDicMapper;
import com.hl.card.common.persistence.dao.SysDicTypeMapper;
import com.hl.card.common.persistence.model.SysDic;
import com.hl.card.common.persistence.model.SysDicType;
import com.hl.card.common.persistence.model.SysDicTypeModel;
import com.hl.card.common.util.DateUtils;
import com.hl.card.common.util.RadomUtil;
import com.hl.card.config.properties.OSSClientUtil;
import com.hl.card.modular.packBack.model.Config;
import com.hl.card.modular.packBack.model.ConfigAction;
import com.hl.card.modular.packBack.model.ConfigChild;
import com.hl.card.modular.packBack.model.ConfigStyle;
import com.hl.card.modular.packBack.model.ConfigType;
import com.hl.card.modular.packBack.model.IConfig;
import com.hl.card.modular.packBack.model.UrlDetail;
import com.hl.card.modular.packBack.service.ConfigService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;

import sun.misc.BASE64Decoder;

/**
 * 配置业务处理类
 * 
 * @author 袁伟
 *
 */
@Service
public class ConfigServiceImpl implements ConfigService<Config> {

	@Autowired
	private MongoTemplate mongoTemplate;
	@Autowired
	private OSSClientUtil oSSClientUtil;
	@Autowired
	private SysDicTypeMapper sysDicTypeMapper;
	@Autowired
	private SysDicMapper sysDicMapper;
	private static String COLLECTION_NAME = "config";
	private static String COLLECTION_TYPE_NAME = "configType";
	private static String COLLECTION_STYLE_NAME = "configStyle";
	private static String COLLECTION_ACTION_NAME = "configAction";

	/**
	 * 配置添加
	 * 
	 * @param config
	 *            抽象配置化参数
	 * @param file
	 *            需要上传的文件
	 * @throws Exception
	 */
	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
	public void addConfig(IConfig config) throws Exception {
		Config c = config.config(); // 回调函数
		c.setConfigCode(getCode("C"));
		c.setAdd_time(DateUtils.getNow(DateUtils.getNow("yyyy-MM-dd HH:mm:ss")));
		c.setUpdate_time(DateUtils.getNow(DateUtils
				.getNow("yyyy-MM-dd HH:mm:ss")));
		List<SysDic> dicList= getDicDetailList();
		for (ConfigChild cc : c.getConfigChilds()) {
			if (cc.getImg() != null && cc.getImg().length() > 0) {
				byte[] s = getInputStream(cc.getImg());
				String name = oSSClientUtil.uploadImg2Oss(s, cc.getSuffix());
				String imgUrl = oSSClientUtil.getImgUrl(name);
				cc.setImg(imgUrl); // 设置图片路径
			}
			cc.setAdd_time(DateUtils.getNow("yyyy-MM-dd HH:mm:ss"));
			cc.setUpdate_time(DateUtils.getNow("yyyy-MM-dd HH:mm:ss"));
			cc.setCode(getCode("N"));
			if (!StringUtils.isEmpty(cc.getUrl())) {
            List<SysDic> filterList = dicList.stream().filter(dic -> dic.getDicTypeNo().equals(cc.getUrl())).collect(Collectors.toList());
			filterList.forEach((x)->{
				if (x.getDicNo().equals("app_url")) {
					cc.setDefault_url(x.getDicValue());
					cc.setApp_url(x.getDicValue());
				} else if (x.getDicNo().equals("web_url")) {
					cc.setWeb_url(x.getDicValue());
				}
				
			});
			}

		}
		mongoTemplate.save(c, COLLECTION_NAME); // 保存配置

	}

	public void getUrlByCode() {

	}

	/**
	 * 解析base64转换为byte[]
	 * 
	 * @param data
	 * @return
	 * @throws IOException
	 */
	public byte[] getInputStream(String data) throws IOException {
		// 通过base64来转化图片
		data = data.replaceAll(
				"^data:image/(png|gif|jpg|jpeg|bmp|tif|psd|ICO);base64,", "");
		BASE64Decoder decoder = new BASE64Decoder();
		// Base64解码
		byte[] imageByte = null;
		try {
			imageByte = decoder.decodeBuffer(data);
			for (int i = 0; i < imageByte.length; ++i) {
				if (imageByte[i] < 0) {// 调整异常数据
					imageByte[i] += 256;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return imageByte;
	}

	/**
	 * 获取编号
	 * 
	 * @param prefix
	 *            前缀
	 * @return 前缀+年月日时分秒+随机字母或数字三位数
	 */
	public String getCode(String prefix) {
		return prefix + DateUtils.getNow("yyyyMMddHHmmss")
				+ RadomUtil.getRandomSalt(3);
	}

	/**
	 * 配置修改
	 * 
	 * @param config
	 *            抽象配置化参数
	 * @param file
	 *            需要上传的文件
	 * @throws Exception
	 */
	public void updateConfig(IConfig config) throws Exception {
		Config c = config.config(); // 回调函数
		Config oldConfig = getConfigByCode(c.getConfigCode()); // 查询配置
		Query query = Query.query(Criteria.where("configCode").is(
				c.getConfigCode()));
		List<ConfigChild> oldList = oldConfig.getConfigChilds();
		Update update = new Update();
		List<SysDic> dicList= getDicDetailList();
		for (ConfigChild cc : c.getConfigChilds()) {
			for (ConfigChild oc : oldList) {
				if (cc.getCode() != null) {
					if (cc.getCode().equals(oc.getCode())) {
						if (cc.getImg() != null && cc.getImg().length() > 0) {
							byte[] s = getInputStream(cc.getImg());
							String name = oSSClientUtil.uploadImg2Oss(s,
									cc.getSuffix());
							String imgUrl = oSSClientUtil.getImgUrl(name);
							cc.setImg(imgUrl); // 设置图片路径
						} else {
							cc.setImg(oc.getImg());
						}
						break;
					}
				} else {
					cc.setCode(getCode("N"));
				}
			}
			if (!StringUtils.isEmpty(cc.getUrl())) {
	            List<SysDic> filterList = dicList.stream().filter(dic -> dic.getDicTypeNo().equals(cc.getUrl())).collect(Collectors.toList());
	    		filterList.forEach((x)->{
					if (x.getDicNo().equals("app_url")) {
						cc.setDefault_url(x.getDicValue());
						cc.setApp_url(x.getDicValue());
					} else if (x.getDicNo().equals("web_url")) {
						cc.setWeb_url(x.getDicValue());
					}
					
				});
			}
		}

		update.set("configName", c.getConfigName());
		update.set("configType", c.getConfigType());
		update.set("configViewSize", c.getConfigViewSize());
		update.set("configStyle", c.getConfigStyle());
		update.set("remark", c.getRemark());
		update.set("update_time", DateUtils.getNow("yyyy-MM-dd HH:mm:ss"));
		update.set("configChilds", c.getConfigChilds());
		mongoTemplate.updateFirst(query, update, Config.class, COLLECTION_NAME); // 保存配置
	}

	/**
	 * 配置删除
	 * 
	 * @param config
	 *            抽象配置化参数
	 */
	public void removeConfig(IConfig config) {
		Config c = config.config(); // 回调函数
		Query query = Query.query(Criteria.where("configCode").is(
				c.getConfigCode()));
		mongoTemplate.remove(query, COLLECTION_NAME);

	}

	/**
	 * 配置查询
	 * 
	 * @param config
	 *            抽象配置化参数
	 */
	public Config searchConfig(IConfig config) {
		Config c = config.config(); // 回调函数
		Query query = new Query();
		query.addCriteria(Criteria.where("configName").is(c.getConfigName()));
		Config resultConfig = mongoTemplate.findOne(query, Config.class,
				COLLECTION_NAME);
		return resultConfig;
	}

	@Override
	public List<Config> configList(Page<Config> page, String configName) {
		Query query = new Query();
		query.with(new Sort(new Sort.Order(Sort.Direction.DESC, "add_time")));
		if (!StringUtils.isEmpty(configName)) {
			query.addCriteria(Criteria.where("configName").is(configName));
		}
		int skip = (page.getCurrent() - 1) * page.getSize();
		query.skip(skip);// 从那条记录开始
		query.limit(page.getSize());// 取多少条记录
		page.setTotal((int) mongoTemplate.count(query, Config.class,
				COLLECTION_NAME));
		return mongoTemplate.find(query, Config.class, COLLECTION_NAME);
	}

	/**
	 * 根据编号查找配置
	 */
	@Override
	public Config getConfigByCode(String configCode) {
		Query query = new Query();
		query.addCriteria(Criteria.where("configCode").is(configCode));
		Config resultConfig = mongoTemplate.findOne(query, Config.class,
				COLLECTION_NAME);
		return resultConfig;
	}

	@Override
	public List<ConfigType> selectConfigTypeList() {

		Document queryObject = new Document();
		Document fields = new Document();
		fields.put("configType", true);
		Query query = new BasicQuery(queryObject, fields);
		List<ConfigType> list = initConfigType();
		List<ConfigType> resultConfig = mongoTemplate.find(query,
				ConfigType.class, COLLECTION_NAME);
		resultConfig.forEach((x) -> {
			if (list.contains(x)) {
				list.remove(x); // 排除已经使用的配置类型
			}
		});
		return list;
	}

	public List<ConfigType> initConfigType() {
		List<ConfigType> list = mongoTemplate.findAll(ConfigType.class,
				COLLECTION_TYPE_NAME); // 获取所有配置类型
		return list;
	}

	public List<ConfigStyle> selectConfigStyleList() {
		List<ConfigStyle> list = mongoTemplate.findAll(ConfigStyle.class,
				COLLECTION_STYLE_NAME); // 获取所有配置样式
		return list;
	}

	public List<ConfigAction> selectConfigActionList() {
		List<ConfigAction> list = mongoTemplate.findAll(ConfigAction.class,
				COLLECTION_ACTION_NAME); // 获取所有配置指令
		return list;
	}

	@Override
	public List<SysDicTypeModel> getDicList() {
		return sysDicTypeMapper.getDicList();
	}
   
	public List<SysDic>  getDicDetailList()
	{
		return sysDicMapper.getDicDetailList();
	}
}
